#ifndef _GAME_ENGINE_H_
#define _GAME_ENGINE_H_

#include "SDL.h"
#include "SDL_gfx/SDL_framerate.h"
#include "render_target.h"
#include "event_target.h"
#include "resource_manager.h"
#include "timer.h"
#include <string>
#include <vector>
#include "button.h"

//The attributes of the screen
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
#define SCREEN_BPP 32
#define PD_FRAMERATE_CAP 60
#define AUDIO_RATE 22050
#define AUDIO_FORMAT AUDIO_S16
#define AUDIO_CHANNELS 2
#define AUDIO_BUFFERS 2048

//Some useful default layers
enum {
	LAYER_BG = 100,
	LAYER_BACK = 200,
	LAYER_MIDDLE = 300,
	LAYER_FRONT = 400
};

class GameEngine : public RenderTarget, public EventTarget
{
public:
	ResourceManager resourceManager;
	std::vector<Timer*> activeTimers;

	GameEngine();
	~GameEngine();

    int Run();
    //static void staticButtonClick(void *obj, Button *button);
	SDL_Surface* getScreen();
	void setScreen(SDL_Surface* screen);
	//Get Scene stack (game engine's children)
	RenderTarget* getSceneStack();
	void addSceneToFront(RenderTarget* scene);
	void addSceneToFront(RenderTarget* scene, std::string id);
	void removeScene(RenderTarget* scene);
	RenderTarget* findSceneById(std::string id);
	void Update(double timeDelta);
	void Render(SDL_Surface* screen);
	void HeartBeat(Timer* timer);
	void addTimer(Timer* timer);
	void removeTimer(Timer* timer);
	static void musicFinished();

	//Singleton access method
	static GameEngine* getInstance();
	static ResourceManager* getResources();
	static void staticHeartBeat(void* param, Timer* timer);
	//Event handlers
	bool OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode);
	bool OnExit();

    static void Shutdown();
protected:
	SDL_Surface* screen;
	bool running, fullscreen, resx, resy, paused;
	bool autoPick;
	Uint32 frame;
	Timer* frameTimer;
    //Manages capping frame rate and getting frame timespan for updates
	FPSmanager fpsManager;
    //The event structure that will be used
    SDL_Event event;
	Uint8 sfxVolume, musicVolume;
	double speed;
    
    int Init();
	bool DispatchEvent(RenderTarget *node, SDL_Event* Event);
};

//THIS IS A TEST TO SEE IF MY UPDATES WORK AND ARE RECOGNIZED.

#endif